package com.kandinfo.base.admin.controller;

import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.quartz.CronScheduleBuilder;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kandinfo.base.admin.domain.ScheduleJob;
import com.kandinfo.base.admin.dto.ScheduleJobDto;
import com.kandinfo.base.admin.dto.ScheduleJobSearchDto;
import com.kandinfo.base.admin.service.ScheduleJobService;
import com.kandinfo.base.common.dto.ResultDto;
import com.kandinfo.base.common.dto.ResultDtoFactory;
import com.kandinfo.base.common.dto.widget.DataTablesResponseDto;
import com.kandinfo.base.common.util.SpringUtils;
import com.kandinfo.base.security.util.RoleConstants;

@RequestMapping(value = "/job")
@Controller
public class QuartzJobController {
	
	private static Logger logger = LoggerFactory.getLogger(QuartzJobController.class);
    
    @Autowired
    private ScheduleJobService scheduleJobService;
    
    @RequiresRoles(value=RoleConstants.SUPER_ADMIN)
    @RequestMapping(value = "/turntopage", method = RequestMethod.GET)
    public String turntojoblistpage(){
        return "job/job_list";
    }
    
    @RequestMapping(value = "/searchbycon",method = RequestMethod.POST)
    @ResponseBody
    public DataTablesResponseDto<ScheduleJobDto> searchByCon(@RequestBody ScheduleJobSearchDto searchDto){
        return scheduleJobService.getSearchByCon(searchDto);
    }
    
    /**
     * 
    * Description: 目前还未完成
    *
    * @param request
    * @param scheduleJob
    * @return
     */
    @SuppressWarnings({ "unused", "rawtypes", "unchecked" })
	@RequestMapping(value = "/add",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto addTask(HttpServletRequest request, @RequestBody ScheduleJob scheduleJob){
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
        } catch (Exception e) {
            return ResultDtoFactory.toNack("cron表达式有误，不能被解析！");
        }
        Object obj = null;
        try {
            if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
                obj = SpringUtils.getBean(scheduleJob.getSpringId());
            } else {
                Class clazz = Class.forName(scheduleJob.getBeanClass());
                obj = clazz.newInstance();
            }
        } catch (Exception e) {
            logger.error("get object error", e);
        }
        if (obj == null) {
            return ResultDtoFactory.toNack("未找到目标类！");
        } else {
            Class clazz = obj.getClass();
            Method method = null;
            try {
                method = clazz.getMethod(scheduleJob.getMethodName());
            } catch (Exception e) {
            	logger.error("method error :" + scheduleJob.getMethodName(), e);
            }
            if (method == null) {
                return ResultDtoFactory.toNack("未找到目标方法！");
            }
        }
        if(scheduleJobService.IsThere(scheduleJob)==null){
        	scheduleJob.setIsConcurrent("0");
        	scheduleJob.setJobStatus("0");
            scheduleJobService.addTask(scheduleJob);
            return ResultDtoFactory.toAck("添加成功！");
        }else{
            return ResultDtoFactory.toNack("该定时器已存在");
        }
    }
    
    /**
     * 
    * Description: 更改job状态
    *
    * @param request
    * @param jobId
    * @param cmd
    * @return
     */
    @RequestMapping(value = "/changeJobStatus",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto changeJobStatus(HttpServletRequest request, Long jobId, String cmd){
        try {
            scheduleJobService.changeStatus(jobId, cmd);
        } catch (SchedulerException e) {
            logger.error("cuowu------", e);
        }
        return ResultDtoFactory.toAck("状态修改成功！");
    }
    
    /**
     * 
    * Description: 删除一个job
    *
    * @param jobIds
    * @return
     */
    @RequestMapping(value = "/deletejobs",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto deleteJobById(List<Long> jobIds){
        scheduleJobService.deleteByPrimaryKey(jobIds);
        return ResultDtoFactory.toAck("删除成功!");
    }
    
    /**
     * 
    * Description: 暂停一个job
    *
    * @param jobId
    * @return
     */
    @RequestMapping(value = "/pausejob",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto pauseJobById(Long jobId){
        try {
            scheduleJobService.pauseJob(jobId);
        } catch (SchedulerException e) {
            return ResultDtoFactory.toNack("暂停job失败");
        }
        return ResultDtoFactory.toAck("暂停job成功");
    }
    
    /**
     * 
    * Description: 恢复job
    *
    * @param jobId
    * @return
     */
    @RequestMapping(value = "/resumejob",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto resumeJobById(Long jobId){
        try {
            scheduleJobService.resumeJob(jobId);
        } catch (SchedulerException e) {
            return ResultDtoFactory.toNack("恢复job失败");
        }
        return ResultDtoFactory.toAck("恢复job成功");
    }
    
    /**
     * 
    * Description: 立即执行job
    *
    * @param jobId
    * @return
     */
    @RequestMapping(value = "/immediateExejob",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto immediateExe(Long jobId){
        try {
            scheduleJobService.runAJobNow(jobId);
        } catch (SchedulerException e) {
            return ResultDtoFactory.toNack("执行job失败");
        }
        return ResultDtoFactory.toAck("执行job成功");
    }
    
    /**
     * 
    * Description: 根据ID获取job相关信息
    *
    * @param jobId
    * @return
     */
    @RequestMapping(value = "/toedit",method = RequestMethod.POST)
    @ResponseBody
    public ScheduleJob getScheduleJobByJobId(Long jobId){
        return scheduleJobService.selectByPrimaryKey(jobId);
    }
    
    /**
     * 
    * Description: 更新job内容
    *
    * @param job
    * @return
     */
    @SuppressWarnings("unused")
	@RequestMapping(value = "/doedit",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto updateJobByJobId(@RequestBody ScheduleJobDto jobDto){
    	Long id = jobDto.getJobId();
    	if (id == null) {
   		 return ResultDtoFactory.toNack("job不存在！");
		}
    	ScheduleJob job = scheduleJobService.findOne(id);
    	if (job == null) {
    		 return ResultDtoFactory.toNack("job不存在！");
		}
    	job.setBeanClass(jobDto.getBeanClass());
    	job.setCronExpression(jobDto.getCronExpression());
    	job.setDescription(jobDto.getJobGroup());
    	job.setJobGroup(jobDto.getJobGroup());
    	job.setJobName(jobDto.getJobName());
    	job.setMethodName(jobDto.getMethodName());
    	job.setSpringId(jobDto.getSpringId());
        scheduleJobService.updateByPrimaryKey(job);
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
        } catch (Exception e1) {
            return ResultDtoFactory.toNack("cron表达式有误，不能被解析！");
        }
        try {
            ScheduleJob ss = scheduleJobService.selectByPrimaryKey(job.getId());
            if("1".equals(ss.getJobStatus()))
            scheduleJobService.updateJobCron(job);
        } catch (SchedulerException e) {
            return ResultDtoFactory.toNack("更新job时间表达式失败");
        }
        return ResultDtoFactory.toAck("更新成功！");
       
    }
    
    @RequestMapping(value = "/deleteone",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto delete(Long id){
        return scheduleJobService.deleteOne(id);
    }
    
    @RequestMapping(value = "/deleteids",method = RequestMethod.POST)
    @ResponseBody
    public ResultDto deleteids(String ids){
        return scheduleJobService.delete(ids);
    }

}
